home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Light ROM 1
/
LIGHT-ROM 1 (Amiga Library Services)(1994).iso
/
ffdisks
/
d928.lha
/
PriMan
/
PriMan.c
< prev
next >
Wrap
C/C++ Source or Header
|
1993-10-07
|
51KB
|
1,077 lines
/*
Task Priority Manager
Copyright 1993 Barry McConnell
bmccnnll@unix1.tcd.ie
*/
#include <exec/types.h>
#include <exec/memory.h>
#include <exec/execbase.h>
#include <dos/dos.h>
#include <dos/dosextens.h>
#include <intuition/intuition.h>
#include <intuition/gadgetclass.h>
#include <intuition/screens.h>
#include <graphics/text.h>
#include <graphics/gfxbase.h>
#include <libraries/gadtools.h>
#include <libraries/asl.h>
#include <workbench/startup.h>
#include <workbench/workbench.h>
#include <proto/dos.h>
#include <proto/exec.h>
#include <proto/intuition.h>
#include <proto/graphics.h>
#include <proto/gadtools.h>
#include <proto/diskfont.h>
#include <proto/asl.h>
#include <proto/icon.h>
#include <stdio.h>
#include <string.h>
#define WINDOWIDCMP IDCMP_CLOSEWINDOW | IDCMP_REFRESHWINDOW | IDCMP_NEWSIZE | BUTTONIDCMP | LISTVIEWIDCMP | RAWKEY
#define DefFontLength 15 /* including the size */
#define MaxFontLength 30 /* well, have YOU seen any font names longer than this?? */
#define ScrollBarWidth 16
#define LISTGAD 1
#define SLIDERGAD 2
#define BREAKGAD 3
#define KILLGAD 4
#define SETTINGSGAD 5
#define GFONTGAD 6
#define LFONTGAD 7
#define GBOXGAD 8
#define LBOXGAD 9
#define CHECKGAD 10
#define SAVEGAD 11
#define USEGAD 12
#define CANCELGAD 13
void __regargs __chkabort(void) {} /* turn off SAS/C v6 CTRL-C checking */
int showTasks(void);
int handleSettings(struct Screen *, struct Window *,
struct Gadget *, struct Gadget *, struct Gadget *, struct Gadget *,
WORD, WORD, WORD);
struct listType /* standard Node type with extra space to store the original task structure, so we can find it again */
{
struct Node mainNode;
struct Task *mainTask;
};
struct FontRequester *propFontReq = NULL, *monoFontReq = NULL;
struct TextAttr propName = { " ", 0, 0, 0 },
monoName = { " ", 0, 0, 0 };
extern struct ExecBase *SysBase;
static UBYTE *version = "$VER: PriMan 1.0 (03.09.93)";
char *myName = NULL; /* to be filled in from WBStartup message */
int workbench = 0; /* started from CLI or Workbench? */
UWORD osver = 0; /* Kickstart version */
WORD winLeft = 150, winTop = 50, winWidth = 220, winHeight = 270, confirm = 1; /* default settings */
UWORD __chip waitPointer[] =
{
0x0000, 0x0000,
0x0400, 0x07c0,
0x0000, 0x07c0,
0x0100, 0x0380,
0x0000, 0x07e0,
0x07c0, 0x1ff8,
0x1ff0, 0x3fec,
0x3ff8, 0x7fde,
0x3ff8, 0x7fbe,
0x7ffc, 0xff7f,
0x7efc, 0xffff,
0x7ffc, 0xffff,
0x3ff8, 0x7ffe,
0x3ff8, 0x7ffe,
0x1ff0, 0x3ffc,
0x07c0, 0x1ff8,
0x0000, 0x07e0,
0x0000, 0x0000,
};
/*
Display a busy pointer in the current window, and prevent user from
clicking on any gadgets. The immediate flag prevents the short delay
(under 3.x) before the pointer changes.
*/
void busyPointer(struct Window *myWindow, struct Requester *myReq, BOOL immediate)
{
InitRequester(myReq);
Request(myReq, myWindow);
if (osver < 39 || immediate)
SetPointer(myWindow, waitPointer, 16, 16, -6, 0);
else
SetWindowPointer(myWindow, WA_BusyPointer, TRUE,
WA_PointerDelay, TRUE,
TAG_END);
}
/*
Restore the pointer to normal. The keepPointer flag just removes the invisible
requester without restoring the normal pointer image.
*/
void normalPointer(struct Window *myWindow, struct Requester *myReq, BOOL keepPointer)
{
if (!keepPointer)
ClearPointer(myWindow);
EndRequest(myReq, myWindow);
}
/*
Join a text string (task or font name) and a number (priority or size) together.
If it's a task, extra spaces are placed between the two components to make the
string an exact length. If the task has an appropriate CLI number, that will be
added in before the task name.
If it's a font, the routine stops at a dot (i.e. in "x.font"), and places a
single space between it and the size.
There must be length+1 bytes free in dest, because of the \0 char.
*/
void createString(struct Task *task, struct TextAttr *font, char *dest, int length)
{
int numLen, cli, i = 0, j = 0;
char digits[5], clitext[11];
char *name;
APTR bstr;
BYTE maxlen = -1;
if (task) /* dealing with a task or a font? */
{
numLen = sprintf(digits, "%d", task -> tc_Node.ln_Pri); /* saves me writing an integer -> ASCII routine */
if (((task -> tc_Node.ln_Type) == NT_PROCESS) && (cli = ((struct Process *)task) -> pr_TaskNum)) /* is it a process with a CLI attached? */
{
sprintf(clitext, "CLI #%d: ", cli);
for (; (i < length - numLen - 1) && clitext[i]; i++)
dest[i] = clitext[i];
bstr = BADDR(((struct CommandLineInterface *)(BADDR(((struct Process *)task) -> pr_CLI))) -> cli_CommandName);
name = (char *)(bstr)+1;
maxlen = *((BYTE *)bstr);
}
else
name = task -> tc_Node.ln_Name;
}
else /* font */
{
numLen = sprintf(digits, "%d", font -> ta_YSize);
name = font -> ta_Name;
}
for (; (i < length - numLen - 1) && name[j] && maxlen && !((name[j] == '.') && font); i++, j++, maxlen--)
dest[i] = name[j];
do
dest[i++] = ' ';
while ((i < length - numLen) && task); /* only insert one space if it's a font name */
j = 0;
do
dest[i++] = digits[j];
while (digits[j++]);
}
/*
Compare two strings. Like "strcmp" but case-insensitive.
*/
int Compare(char *s, char *t)
{
for (; ((*s & ~32) == (*t & ~32)) && *s; s++, t++) /* sorry, K&R ;-) */
;
return (*s & ~32) - (*t & ~32);
}
/*
Alphabetically insert "node" into "list".
*/
void Sort(struct List *list, struct Node *node)
{
struct Node *temp = list -> lh_Head;
while ((temp -> ln_Succ) && Compare(temp -> ln_Name, node -> ln_Name) < 0)
temp = temp -> ln_Succ;
Insert(list, node, temp -> ln_Pred);
}
/*
Add an Exec task list ("source") onto our own one ("dest").
Allocates memory as necessary, and preserves alphabetical order.
If we just want to add one task, use the last parameter ("single") -
in this case, "source" will be ignored.
*/
int BuildList(struct List *source, struct List *dest, struct Remember **memoryKey, int taskLength, struct Task *single)
{
struct Node *execNode;
struct listType *taskNode;
int success = TRUE;
UBYTE *taskString;
if (single)
{
if ((taskNode = AllocRemember(memoryKey, sizeof(struct listType), MEMF_ANY))
&& (taskString = AllocRemember(memoryKey, taskLength + 1, MEMF_ANY)))
{
createString(single, NULL, taskString, taskLength);
taskNode -> mainNode.ln_Name = taskString;
taskNode -> mainNode.ln_Pri = single -> tc_Node.ln_Pri;
taskNode -> mainTask = single;
Sort(dest, (struct Node *)taskNode);
}
else
success = FALSE;
}
else
{
for (execNode = source -> lh_Head; (execNode -> ln_Succ) && success; execNode = execNode -> ln_Succ)
{
if ((taskNode = AllocRemember(memoryKey, sizeof(struct listType), MEMF_ANY))
&& (taskString = AllocRemember(memoryKey, taskLength + 1, MEMF_ANY)))
{
createString((struct Task *)execNode, NULL, taskString, taskLength);
taskNode -> mainNode.ln_Name = taskString;
taskNode -> mainNode.ln_Pri = execNode -> ln_Pri;
taskNode -> mainTask = (struct Task *)execNode;
Sort(dest, (struct Node *)taskNode);
}
else
success = FALSE;
}
}
return success;
}
/*
Search for given ToolType in array.
Fills in string -> decimal value if found.
*/
void match(char *tool, char **array, WORD *value)
{
char *string;
int temp;
if (string = FindToolType(array, tool)) /* is it there? */
{
sscanf(string, "%d", &temp); /* read it into type "int" */
*value = temp; /* convert to "word" */
}
}
void main(int argc, char *argv[])
{
struct DiskObject *myIcon;
char **tools, *string;
if (IntuitionBase = (struct IntuitionBase *)OpenLibrary("intuition.library", 37))
{
if (GfxBase = (struct GfxBase *)OpenLibrary("graphics.library", 37))
{
if (GadToolsBase = OpenLibrary("gadtools.library", 37))
{
if (IconBase = OpenLibrary("icon.library", 37))
{
osver = SysBase -> LibNode.lib_Version; /* running under 2.0, 3.0, ...? */
if (workbench = !argc) /* only look at ToolTypes if started from Workbench */
{
myName = ((struct WBStartup *)argv) -> sm_ArgList -> wa_Name; /* find ourselves */
if (myIcon = GetDiskObject(myName)); /* read in .info file */
{
tools = myIcon -> do_ToolTypes;
match("LEFT", tools, &winLeft); /* start searching for valid ToolTypes */
match("TOP", tools, &winTop);
match("WIDTH", tools, &winWidth);
match("HEIGHT", tools, &winHeight);
match("GADSIZE", tools, &(propName.ta_YSize));
match("LISTSIZE", tools, &(monoName.ta_YSize));
if (string = FindToolType(tools, "GADFONT"))
sscanf(string, "%s", propName.ta_Name);
if (string = FindToolType(tools, "LISTFONT"))
sscanf(string, "%s", monoName.ta_Name);
if (string = FindToolType(tools, "CONFIRM"))
confirm = !(string[0] == 'N' && string[1] == 'O'); /* user must be exact! */
FreeDiskObject(myIcon);
}
}
propFontReq = AllocAslRequest(ASL_FontRequest, NULL);
monoFontReq = AllocAslRequest(ASL_FontRequest, NULL);
while (showTasks())
;
FreeAslRequest(propFontReq);
FreeAslRequest(monoFontReq);
CloseLibrary(IconBase);
}
CloseLibrary(GadToolsBase);
}
CloseLibrary((struct Library *)GfxBase);
}
CloseLibrary((struct Library *)IntuitionBase);
}
}
int showTasks(void)
{
static struct Window *myWindow; /* allow resizing without closing it */
static int windowValid = FALSE;
struct Screen *myScreen;
struct TextFont *propFont, *monoFont;
struct TextExtent fontSize = { NULL, NULL };
struct RastPort myRast;
struct Image blank = { NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL };
struct IntuiMessage *message;
struct Task *currentTask;
struct List taskList;
struct Remember *memoryKey;
struct Requester tinyReq;
struct Node *current;
struct NewGadget myGad;
struct Gadget *mainGads, *setGads, *prevGad, *prevGad2, *selectedGad,
*listGad, *sliderGad, *breakGad, *killGad, *propFontGad, *monoFontGad, *checkGad;
void *visInfo;
WORD height, width, sysHeight, sysWidth, windowTop, listWidth, buttonWidth, minWidth, minHeight,
setWidth, setHeight, buttonText, fontText, confirmText, cancelText, code;
ULONG class;
int taskLength, exit = 0, redraw = 0, preserve = 0, update = 0, wide = 0, pos, button;
struct EasyStruct about = /* And the user thought he was getting full online help... */
{
sizeof(struct EasyStruct),
0,
"About PriMan",
"Task Priority Manager v1.0\nFreely Distributable\nCopyright 1993 Barry McConnell\nbmccnnll@unix1.tcd.ie",
"Okay"
};
struct EasyStruct lost = /* Oi! Where did that task go? */
{
sizeof(struct EasyStruct),
0,
"PriMan trouble",
"Task was not found!",
"Okay"
};
struct EasyStruct signal =
{
sizeof(struct EasyStruct),
0,
"PriMan warning",
"Really signal `%s'\nwith Ctrl-C?",
"Signal|Cancel"
};
struct EasyStruct kill =
{
sizeof(struct EasyStruct),
0,
"PriMan warning",
"Really remove `%s'?",
"Remove|Cancel"
};
if (myScreen = LockPubScreen(NULL))
{
if (visInfo = GetVisualInfo(myScreen, TAG_END))
{
if (!propName.ta_YSize || propName.ta_Name[0] == ' ') /* invalid font structure */
{
propName.ta_YSize = myScreen -> Font -> ta_YSize;
strcpy(propName.ta_Name, myScreen -> Font -> ta_Name);
}
if (!monoName.ta_YSize || monoName.ta_Name[0] == ' ')
{
monoName.ta_YSize = GfxBase -> DefaultFont -> tf_YSize;
strcpy(monoName.ta_Name, GfxBase -> DefaultFont -> tf_Message.mn_Node.ln_Name);
}
if ((propFont = OpenDiskFont(&propName)) && (monoFont = OpenDiskFont(&monoName)))
{
FontExtent(propFont, &fontSize); /* figure out pixel size of fonts */
height = fontSize.te_Height;
width = fontSize.te_Width;
FontExtent(monoFont, &fontSize);
sysHeight = fontSize.te_Height;
sysWidth = fontSize.te_Width;
InitRastPort(&myRast); /* dummy RastPort for getting string lengths */
myRast.Font = propFont;
buttonText = TextLength(&myRast, "Settings...", 11) + INTERWIDTH * 2;
fontText = TextLength(&myRast, "Gadget Font...", 14) + INTERWIDTH * 2;
confirmText = TextLength(&myRast, "Confirm actions?", 16);
cancelText = TextLength(&myRast, "Cancel", 6) + INTERWIDTH * 2;
windowTop = (myScreen -> WBorTop) + myScreen -> Font -> ta_YSize + 1 + INTERHEIGHT;
listWidth = sysWidth * 7 + ScrollBarWidth + INTERWIDTH * 3 + (osver < 39 ? 4 : 0); /* full width of a small window (a bug in 2.x clips 4 pixels too early) */
buttonWidth = buttonText * 3 + INTERWIDTH * 4; /* width of buttons and spacing */
minWidth = buttonWidth > listWidth ? buttonWidth : listWidth; /* choose between them */
minHeight = windowTop + sysHeight * (osver < 39 ? 5 : 3) + height + INTERHEIGHT * 8 + 2; /* small ListView (1 or 2 elements) */
if (winWidth < minWidth) /* so, which is it to be? */
winWidth = minWidth;
if (winWidth > myScreen -> Width)
winWidth = myScreen -> Width;
if (winHeight < minHeight)
winHeight = minHeight;
if (winHeight > myScreen -> Height)
winHeight = myScreen -> Height;
taskLength = (winWidth - ScrollBarWidth - INTERWIDTH * 3 - (osver < 39 ? 4 : 0)) / sysWidth;
mainGads = NULL; /* begin laying out gadgets for main window */
prevGad = CreateContext(&mainGads);
myGad.ng_LeftEdge = INTERWIDTH;
myGad.ng_TopEdge = windowTop;
myGad.ng_Width = winWidth - INTERWIDTH * 2;
myGad.ng_Height = winHeight - windowTop - sysHeight - height - INTERHEIGHT * 7 - 2;
myGad.ng_GadgetText = NULL;
myGad.ng_TextAttr = &monoName;
myGad.ng_GadgetID = LISTGAD;
myGad.ng_Flags = NULL;
myGad.ng_VisualInfo = visInfo;
prevGad = listGad = CreateGadget(LISTVIEW_KIND, prevGad, &myGad,
GTLV_Labels, NULL,
GTLV_ShowSelected, NULL,
TAG_END);
if (!(windowValid || osver < 39)) /* if possible, silently adjust its height for perfect spacing */
{
winHeight += listGad -> Height - myGad.ng_Height; /* A bug in 2.x doesn't give the correct value */
myGad.ng_Height = listGad -> Height; /* ListView may have ended up smaller */
}
myGad.ng_LeftEdge += sysWidth * 4 + INTERWIDTH;
myGad.ng_TopEdge += myGad.ng_Height + INTERHEIGHT;
myGad.ng_Width = winWidth - INTERWIDTH - myGad.ng_LeftEdge;
myGad.ng_Height = sysHeight + INTERHEIGHT;
myGad.ng_GadgetID = SLIDERGAD;
prevGad = sliderGad = CreateGadget(SLIDER_KIND, prevGad, &myGad,
GTSL_Min, -25,
GTSL_Max, 25,
GTSL_Level, 0,
GTSL_LevelFormat, "%4ld",
GTSL_MaxLevelLen, 4,
GTSL_LevelPlace, PLACETEXT_LEFT,
GA_RelVerify, TRUE,
GA_Disabled, TRUE,
TAG_END);
myGad.ng_LeftEdge = INTERWIDTH;
myGad.ng_TopEdge += myGad.ng_Height + INTERHEIGHT;
myGad.ng_Width = buttonText;
myGad.ng_Height = height + INTERHEIGHT;
myGad.ng_GadgetText = "Break";
myGad.ng_TextAttr = &propName;
myGad.ng_GadgetID = BREAKGAD;
prevGad = breakGad = CreateGadget(BUTTON_KIND, prevGad, &myGad,
GA_Disabled, TRUE,
TAG_END);
myGad.ng_LeftEdge += buttonText + (winWidth - INTERWIDTH *2 - buttonText * 3) / 2;
myGad.ng_GadgetText = "Kill";
myGad.ng_GadgetID = KILLGAD;
prevGad = killGad = CreateGadget(BUTTON_KIND, prevGad, &myGad,
GA_Disabled, TRUE,
TAG_END);
myGad.ng_LeftEdge += buttonText + (winWidth - INTERWIDTH *2 - buttonText * 3) / 2;
myGad.ng_GadgetText = "Settings...";
myGad.ng_GadgetID = SETTINGSGAD;
prevGad = CreateGadget(BUTTON_KIND, prevGad, &myGad, TAG_END);
setGads = NULL; /* now the settings window */
prevGad2 = CreateContext(&setGads);
myGad.ng_LeftEdge = INTERWIDTH;
myGad.ng_TopEdge = windowTop;
myGad.ng_Width = fontText;
myGad.ng_GadgetText = "Gadget Font...";
myGad.ng_GadgetID = GFONTGAD;
prevGad2 = CreateGadget(BUTTON_KIND, prevGad2, &myGad, TAG_END);
myGad.ng_LeftEdge += confirmText + INTERWIDTH;
myGad.ng_Width = width * DefFontLength + INTERWIDTH;
myGad.ng_GadgetText = NULL;
myGad.ng_GadgetID = GBOXGAD;
prevGad2 = propFontGad = CreateGadget(TEXT_KIND, prevGad2, &myGad,
GTTX_Border, TRUE,
TAG_END);
setWidth = myGad.ng_LeftEdge + myGad.ng_Width + INTERWIDTH;
myGad.ng_LeftEdge = INTERWIDTH;
myGad.ng_TopEdge += myGad.ng_Height + INTERHEIGHT;
myGad.ng_Width = fontText;
myGad.ng_GadgetText = "List Font...";
myGad.ng_GadgetID = LFONTGAD;
prevGad2 = CreateGadget(BUTTON_KIND, prevGad2, &myGad, TAG_END);
myGad.ng_LeftEdge += confirmText + INTERWIDTH;
myGad.ng_Width = width * DefFontLength + INTERWIDTH;
myGad.ng_GadgetText = NULL;
myGad.ng_GadgetID = LBOXGAD;
prevGad2 = monoFontGad = CreateGadget(TEXT_KIND, prevGad2, &myGad,
GTTX_Border, TRUE,
TAG_END);
myGad.ng_LeftEdge = INTERWIDTH;
myGad.ng_TopEdge += myGad.ng_Height + INTERHEIGHT;
myGad.ng_Width = confirmText;
myGad.ng_Height = height + INTERHEIGHT;
myGad.ng_TextAttr = &propName;
myGad.ng_GadgetID = NULL;
prevGad2 = CreateGadget(TEXT_KIND, prevGad2, &myGad,
GTTX_Text, "Confirm actions?",
TAG_END);
myGad.ng_LeftEdge += myGad.ng_Width + INTERWIDTH;
myGad.ng_TopEdge += (height + INTERHEIGHT - 11) / 2;
myGad.ng_GadgetID = CHECKGAD;
prevGad2 = checkGad = CreateGadget(CHECKBOX_KIND, prevGad2, &myGad, TAG_END);
myGad.ng_LeftEdge = INTERWIDTH;
myGad.ng_TopEdge += height + INTERHEIGHT * 2 - (height + INTERHEIGHT - 11) / 2;
myGad.ng_Width = cancelText;
myGad.ng_GadgetText = "Save";
myGad.ng_GadgetID = SAVEGAD;
prevGad2 = CreateGadget(BUTTON_KIND, prevGad2, &myGad,
GA_Disabled, !workbench, /* CLI users can't open the .info file */
TAG_END);
myGad.ng_LeftEdge += cancelText + (setWidth - INTERWIDTH *2 - cancelText * 3) / 2;
myGad.ng_GadgetText = "Use";
myGad.ng_GadgetID = USEGAD;
prevGad2 = CreateGadget(BUTTON_KIND, prevGad2, &myGad, TAG_END);
myGad.ng_LeftEdge += cancelText + (setWidth - INTERWIDTH *2 - cancelText * 3) / 2;
myGad.ng_GadgetText = "Cancel";
myGad.ng_GadgetID = CANCELGAD;
prevGad2 = CreateGadget(BUTTON_KIND, prevGad2, &myGad, TAG_END);
setHeight = myGad.ng_TopEdge + myGad.ng_Height + INTERHEIGHT + 2;
if (prevGad && prevGad2)
{
if (windowValid) /* it may already be open and just needs updating */
{
AddGList(myWindow, mainGads, ~0, -1, NULL);
RefreshGList(mainGads, myWindow, NULL, -1);
windowValid = FALSE;
}
else
myWindow = OpenWindowTags(NULL, WA_Title, "Task Priority Manager",
WA_Gadgets, mainGads,
WA_Left, winLeft,
WA_Top, winTop,
WA_Width, winWidth,
WA_Height, winHeight,
WA_MinWidth, minWidth,
WA_MinHeight, minHeight,
WA_MaxWidth, ~0,
WA_MaxHeight, ~0,
WA_DragBar, TRUE,
WA_DepthGadget, TRUE,
WA_CloseGadget, TRUE,
WA_SizeGadget, TRUE,
WA_SizeBBottom, TRUE,
WA_Activate, TRUE,
WA_RMBTrap, TRUE,
WA_IDCMP, WINDOWIDCMP,
WA_PubScreen, myScreen,
TAG_END);
if (myWindow) /* either just opened, or else we added the gadget list above */
{
GT_RefreshWindow(myWindow, NULL);
do
{
if (update) /* may need to remove obsolete task list first */
{
GT_SetGadgetAttrs(listGad, myWindow, NULL,
GTLV_Labels, ~0,
TAG_END);
FreeRemember(&memoryKey, TRUE);
exit = update = 0;
}
memoryKey = NULL;
taskList.lh_Head = (struct Node *) &taskList.lh_Tail;
taskList.lh_Tail = NULL;
taskList.lh_TailPred = (struct Node *) &taskList.lh_Head;
Disable(); /* going to walk Exec's task list */
if (BuildList(&(SysBase -> TaskReady), &taskList, &memoryKey, taskLength, NULL)
&& BuildList(&(SysBase -> TaskWait), &taskList, &memoryKey, taskLength, NULL)
&& BuildList(NULL, &taskList, &memoryKey, taskLength, FindTask(NULL)))
{
Enable();
GT_SetGadgetAttrs(listGad, myWindow, NULL,
GTLV_Labels, &taskList,
GTLV_Selected, ~0,
TAG_END);
GT_SetGadgetAttrs(sliderGad, myWindow, NULL,
GA_Disabled, TRUE,
TAG_END);
GT_SetGadgetAttrs(breakGad, myWindow, NULL,
GA_Disabled, TRUE,
TAG_END);
GT_SetGadgetAttrs(killGad, myWindow, NULL,
GA_Disabled, TRUE,
TAG_END);
pos = -1; /* ignore any "leftover" requests to break / kill */
do
{
WaitPort(myWindow -> UserPort);
if (message = GT_GetIMsg(myWindow -> UserPort)) /* GadTools filters out most of them */
{
if ((class = message -> Class) == GADGETUP)
selectedGad = message -> IAddress;
code = message -> Code;
GT_ReplyIMsg(message);
switch (class)
{
case IDCMP_CLOSEWINDOW:
exit = 1;
break;
case IDCMP_NEWSIZE:
exit = redraw = preserve = 1;
break;
case IDCMP_REFRESHWINDOW:
GT_BeginRefresh(myWindow);
GT_EndRefresh(myWindow, TRUE);
break;
case GADGETUP:
switch (selectedGad -> GadgetID)
{
case LISTGAD:
pos = code;
for (current = taskList.lh_Head; code > 0; current = current -> ln_Succ, code --) /* find selected task */
;
if (wide = (current -> ln_Pri < -25 || current -> ln_Pri > 25)) /* wide or narrow scale? */
GT_SetGadgetAttrs(sliderGad, myWindow, NULL,
GTSL_Min, -128,
GTSL_Max, 127,
TAG_END);
else
GT_SetGadgetAttrs(sliderGad, myWindow, NULL,
GTSL_Min, -25,
GTSL_Max, 25,
TAG_END);
GT_SetGadgetAttrs(sliderGad, myWindow, NULL, /* update slider gadget to new task's priority */
GTSL_Level, current -> ln_Pri,
GA_Disabled, FALSE,
TAG_END);
GT_SetGadgetAttrs(breakGad, myWindow, NULL,
GA_Disabled, FALSE,
TAG_END);
GT_SetGadgetAttrs(killGad, myWindow, NULL,
GA_Disabled, FALSE,
TAG_END);
break;
case SLIDERGAD:
currentTask = ((struct listType *)current) -> mainTask;
if (currentTask -> tc_State < 2 || currentTask -> tc_State > 4) /* not a valid task */
{
busyPointer(myWindow, &tinyReq, FALSE);
EasyRequest(NULL, &lost, NULL, NULL);
normalPointer(myWindow, &tinyReq, FALSE);
exit = update = 1;
}
else
{
SetTaskPri(currentTask, (WORD)code);
GT_SetGadgetAttrs(listGad, myWindow, NULL,
GTLV_Labels, ~0,
TAG_END);
createString(currentTask, FALSE, current -> ln_Name, taskLength);
current -> ln_Pri = (WORD)code;
GT_SetGadgetAttrs(listGad, myWindow, NULL,
GTLV_Labels, &taskList,
GTLV_Selected, pos, /* only required under 2.0 */
TAG_END);
}
break;
case BREAKGAD:
case KILLGAD:
if (!(pos == -1))
{
busyPointer(myWindow, &tinyReq, FALSE);
currentTask = ((struct listType *)current) -> mainTask;
if (currentTask -> tc_State < 2 || currentTask -> tc_State > 4)
{
EasyRequest(NULL, &lost, NULL, NULL);
exit = update = 1;
}
else
{
if (confirm)
button = EasyRequest(NULL, (selectedGad -> GadgetID == BREAKGAD) ? &signal : &kill, NULL, currentTask -> tc_Node.ln_Name);
if (button || !confirm) /* user clicked "Okay" */
{
Disable();
if (currentTask -> tc_State >= 2 && currentTask -> tc_State <= 4) /* paranoid! */
{
if (selectedGad -> GadgetID == BREAKGAD)
{
Signal(currentTask, SIGBREAKF_CTRL_C);
Enable();
Delay(25); /* allow time for task to exit */
}
else
{
RemTask(currentTask); /* BLAM! */
Enable();
}
}
exit = update = 1;
}
}
normalPointer(myWindow, &tinyReq, FALSE);
}
break;
case SETTINGSGAD:
WindowLimits(myWindow, winWidth, winHeight, winWidth, winHeight);
busyPointer(myWindow, &tinyReq, FALSE);
if (handleSettings(myScreen, myWindow, setGads, propFontGad, monoFontGad, checkGad, setWidth, setHeight, windowTop))
exit = redraw = 1;
normalPointer(myWindow, &tinyReq, FALSE);
WindowLimits(myWindow, minWidth, minHeight, ~0, ~0);
break;
}
break;
case RAWKEY:
switch (code)
{
case 64:
case 68: /* Space or Return keys */
exit = update = 1;
break;
case 66: /* Tab key */
if (!(pos == -1)) /* don't change the scale of a disabled slider */
{
if (current -> ln_Pri > -26 && current -> ln_Pri < 26) /* don't want to end up off the scale! */
{
if (wide = 1 - wide)
GT_SetGadgetAttrs(sliderGad, myWindow, NULL,
GTSL_Min, -128,
GTSL_Max, 127,
TAG_END);
else
GT_SetGadgetAttrs(sliderGad, myWindow, NULL,
GTSL_Min, -25,
GTSL_Max, 25,
TAG_END);
}
}
break;
case 95: /* Help key */
busyPointer(myWindow, &tinyReq, FALSE);
EasyRequest(NULL, &about, NULL, NULL);
normalPointer(myWindow, &tinyReq, FALSE);
break;
}
break;
}
}
}
while (!exit);
}
else
Enable();
}
while (update);
winLeft = myWindow -> LeftEdge;
winTop = myWindow -> TopEdge;
winWidth = myWindow -> Width;
winHeight = myWindow -> Height;
if (preserve)
{
windowValid = TRUE;
blank.Width = winWidth - INTERWIDTH * 3 / 2; /* don't blank borders */
blank.Height = winHeight - windowTop - INTERHEIGHT * 2 - 2;
RemoveGList(myWindow, mainGads, -1); /* we'll leave the actual window open */
EraseImage(myWindow -> RPort, &blank, INTERWIDTH, windowTop);
RefreshWindowFrame(myWindow); /* because it's probably a mess by now... */
}
else
CloseWindow(myWindow);
FreeRemember(&memoryKey, TRUE);
}
}
FreeGadgets(mainGads);
FreeGadgets(setGads);
CloseFont(monoFont);
CloseFont(propFont);
}
FreeVisualInfo(visInfo);
}
UnlockPubScreen(NULL, myScreen);
}
return redraw;
}
int handleSettings(struct Screen *myScreen, struct Window *mainWindow,
struct Gadget *setGads, struct Gadget *propFontGad, struct Gadget *monoFontGad, struct Gadget *checkGad,
WORD setWidth, WORD setHeight, WORD windowTop)
{
struct Window *setWindow;
struct IntuiMessage *message;
struct Gadget *selectedGad;
struct Requester tinyReq;
WORD tempConfirm, action = 1, newPropFont = 0, newMonoFont = 0;
UWORD class;
char propString[DefFontLength + 1], monoString[DefFontLength + 1],
tempPropName[MaxFontLength], tempMonoName[MaxFontLength];
struct DiskObject *myIcon;
char **oldTools, **currentTool, *newTools[20], empty[9][MaxFontLength + 10], *string;
int tempPropSize, tempMonoSize, oldPos, newPos;
if (setWindow = OpenWindowTags(NULL, WA_Title, "PriMan Settings",
WA_Gadgets, setGads,
WA_Left, mainWindow -> LeftEdge,
WA_Top, mainWindow -> TopEdge + windowTop - INTERHEIGHT,
WA_Width, setWidth,
WA_Height, setHeight,
WA_DragBar, TRUE,
WA_DepthGadget, TRUE,
WA_Activate, TRUE,
WA_CloseGadget, TRUE,
WA_RMBTrap, TRUE,
WA_IDCMP, WINDOWIDCMP,
WA_PubScreen, myScreen,
TAG_END))
{
GT_RefreshWindow(setWindow, NULL);
action = 0;
tempConfirm = confirm; /* so we can restore it if the user clicks "Cancel" */
createString(FALSE, &propName, propString, DefFontLength); /* initial setting for the text box */
createString(FALSE, &monoName, monoString, DefFontLength);
strcpy(tempPropName, propName.ta_Name); /* initial setting for the font requester */
strcpy(tempMonoName, monoName.ta_Name);
tempPropSize = propName.ta_YSize;
tempMonoSize = monoName.ta_YSize;
GT_SetGadgetAttrs(propFontGad, setWindow, NULL,
GTTX_Text, propString,
TAG_END);
GT_SetGadgetAttrs(monoFontGad, setWindow, NULL,
GTTX_Text, monoString,
TAG_END);
GT_SetGadgetAttrs(checkGad, setWindow, NULL,
GTCB_Checked, confirm,
TAG_END);
do
{
WaitPort(setWindow -> UserPort);
message = GT_GetIMsg(setWindow -> UserPort);
class = message -> Class;
selectedGad = message -> IAddress;
GT_ReplyIMsg(message);
switch (class)
{
case IDCMP_CLOSEWINDOW:
SetPointer(setWindow, waitPointer, 16, 16, -6, 0); /* helps prevent "flashing" */
action = 1;
break;
case IDCMP_REFRESHWINDOW:
GT_BeginRefresh(setWindow);
GT_EndRefresh(setWindow, TRUE);
break;
case GADGETUP:
switch (selectedGad -> GadgetID)
{
case CHECKGAD:
tempConfirm = (selectedGad -> Flags) & GFLG_SELECTED;
break;
case GFONTGAD:
busyPointer(setWindow, &tinyReq, FALSE);
if (newPropFont = AslRequestTags(propFontReq, ASL_Hail, "Select Gadget Font",
ASL_FuncFlags, NULL,
ASL_LeftEdge, setWindow -> LeftEdge,
ASL_TopEdge, setWindow -> TopEdge + windowTop - INTERHEIGHT,
ASL_FontName, tempPropName,
ASL_FontHeight, tempPropSize,
TAG_END))
{
createString(FALSE, &(propFontReq -> fo_Attr), propString, DefFontLength);
GT_SetGadgetAttrs(propFontGad, setWindow, NULL,
GTTX_Text, propString,
TAG_END);
strcpy(tempPropName, propFontReq -> fo_Attr.ta_Name);
tempPropSize = propFontReq -> fo_Attr.ta_YSize;
}
normalPointer(setWindow, &tinyReq, FALSE);
break;
case LFONTGAD:
busyPointer(setWindow, &tinyReq, FALSE);
if (newMonoFont = AslRequestTags(monoFontReq, ASL_Hail, "Select Task List Font",
ASL_FuncFlags, FONF_FIXEDWIDTH,
ASL_LeftEdge, setWindow -> LeftEdge,
ASL_TopEdge, setWindow -> TopEdge + windowTop - INTERHEIGHT,
ASL_FontName, tempMonoName,
ASL_FontHeight, tempMonoSize,
TAG_END))
{
createString(FALSE, &(monoFontReq -> fo_Attr), monoString, DefFontLength);
GT_SetGadgetAttrs(monoFontGad, setWindow, NULL,
GTTX_Text, monoString,
TAG_END);
strcpy(tempMonoName, monoFontReq -> fo_Attr.ta_Name);
tempMonoSize = monoFontReq -> fo_Attr.ta_YSize;
}
normalPointer(setWindow, &tinyReq, FALSE);
break;
case SAVEGAD:
case USEGAD:
busyPointer(setWindow, &tinyReq, TRUE);
action = 1;
confirm = tempConfirm;
if (newPropFont && (strcmp((propFontReq -> fo_Attr).ta_Name, propName.ta_Name)
|| !((propFontReq -> fo_Attr).ta_YSize == propName.ta_YSize)))
{
strcpy(propName.ta_Name, (propFontReq -> fo_Attr).ta_Name);
propName.ta_YSize = (propFontReq -> fo_Attr).ta_YSize;
action = 2;
}
if (newMonoFont && (strcmp((monoFontReq -> fo_Attr).ta_Name, monoName.ta_Name)
|| !((monoFontReq -> fo_Attr).ta_YSize == monoName.ta_YSize)))
{
strcpy(monoName.ta_Name, (monoFontReq -> fo_Attr).ta_Name);
monoName.ta_YSize = (monoFontReq -> fo_Attr).ta_YSize;
action = 2;
}
if (selectedGad -> GadgetID == SAVEGAD)
{
if (myIcon = GetDiskObject(myName));
{
currentTool = oldTools = myIcon -> do_ToolTypes; /* existing ToolTypes */
oldPos = newPos = 0;
while (string = currentTool[oldPos++])
if (strncmp(string, "LEFT", 4) && strncmp(string, "TOP", 3)
&& strncmp(string, "WIDTH", 5) && strncmp(string, "HEIGHT", 6)
&& strncmp(string, "GADFONT", 7) && strncmp(string, "GADSIZE", 7)
&& strncmp(string, "LISTFONT", 8) && strncmp(string, "LISTSIZE", 8)
&& strncmp(string, "CONFIRM", 7)) /* get rid of our ones */
newTools[newPos++] = string;
sprintf(empty[0], "LEFT=%d", mainWindow -> LeftEdge);
sprintf(empty[1], "TOP=%d", mainWindow -> TopEdge);
sprintf(empty[2], "WIDTH=%d", mainWindow -> Width);
sprintf(empty[3], "HEIGHT=%d", mainWindow -> Height);
sprintf(empty[4], "GADFONT=%s", propName.ta_Name);
sprintf(empty[5], "GADSIZE=%d", propName.ta_YSize);
sprintf(empty[6], "LISTFONT=%s", monoName.ta_Name);
sprintf(empty[7], "LISTSIZE=%d", monoName.ta_YSize);
sprintf(empty[8], "CONFIRM=%s", confirm ? "YES" : "NO");
for (oldPos = 0; oldPos < 9;)
newTools[newPos++] = empty[oldPos++]; /* write out our ones at end */
newTools[newPos] = NULL; /* end of list */
myIcon -> do_ToolTypes = newTools;
PutDiskObject(myName, myIcon);
myIcon -> do_ToolTypes = oldTools; /* restore original pointer before freeing memory */
FreeDiskObject(myIcon);
}
}
normalPointer(setWindow, &tinyReq, TRUE);
break;
case CANCELGAD:
SetPointer(setWindow, waitPointer, 16, 16, -6, 0);
action = 1;
break;
}
break;
}
}
while (!action);
CloseWindow(setWindow);
}
return action - 1;
}